﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetDon.OA.Data.CollectionClasses;
using NetDon.OA.Data.EntityClasses;
using NetDon.OA.Data.HelperClasses;
using NetDon.OA.Data.Linq;
using NetDon.OA.Interface.Admin;
using SD.LLBLGen.Pro.ORMSupportClasses;

namespace NetDon.OA.Business.Admin
{
    public class PostService : PrimitiveHierarchyService<PostData>, IPostService
    {
        public PostService()
            : base("PostData")
        {
        }
        #region IPostService Members

        public PostDataCollection GetChildPosts(Guid postId)
        {
            return new PostDataCollection(GetChildNodes(postId).OrderBy(i => i.PostName).ToArray());
        }

        public PostDataCollection GetRootPosts()
        {
            return new PostDataCollection(GetRootNodes().OrderBy(i => i.PostName).ToArray());
        }

        public PostData GetPost(Guid postId)
        {
            return GetData(postId);
        }
        public string GetPostName(Guid postId)
        {
            PostData post = GetData(postId);
            if (post != null)
            {
                return post.PostName;
            }
            else
            {
                return string.Empty;
            }
        }
        public bool RemovePost(Guid postId)
        {
            return RemoveData(postId);
        }
        //public int GetUserPositionLevel(Guid userId)
        //{
        //    var meta = new LinqMetaData();
        //    var level = 0;
        //    var currentUser = meta.User.Where(u => u.UserId == userId).FirstOrDefault();
        //    if (currentUser != null)
        //    {
        //        var currentPost = meta.Post.Where(p => p.PostId == currentUser.PositionId).FirstOrDefault();
        //        if (currentPost != null)
        //        {
        //            var dictionary = meta.Dictionary.Where(d => d.Oid == currentPost.PostLevel).FirstOrDefault();
        //            if (dictionary != null) int.TryParse(dictionary.FieldValue, out level);
        //        }
        //    }
        //    return level;
        //}
        public bool CheckPostUsed(Guid postId)
        {
            var post = GetPost(postId);
            if (post == null)
            {
                return false;
            }

            return new PostCollection().GetDbCount(PostFields.ParentPostId == postId) > 0 ||

                new UserCollection().GetDbCount(UserFields.PositionId == postId) > 0;
        }

        public bool AddPost(PostData postData)
        {
            return AddData(postData);
        }

        public bool ModifyPost(PostData postData)
        {
            return ModifyData(postData.PostId, postData);
        }
        #endregion


        #region Overrides of CachableServiceBase<PostData>

        protected override PostData OnLoadData(object key, ITransaction transaction)
        {
            var meta = new LinqMetaData(transaction);
            List<PostEntity> list = (from post in meta.Post
                                     where post.PostId == (Guid)key
                                     select post).ToList();
            return list.Count > 0 ? GetPostData(list[0]) : null;
        }

        protected override object GetDataKey(PostData data)
        {
            return data.PostId;
        }

        protected override bool OnRemoveData(object key, PostData data, ITransaction transaction)
        {
            if (base.OnRemoveData(key, data, transaction))
            {
                var collection = new Data.CollectionClasses.PostCollection();
                transaction.Add(collection);
                return collection.DeleteMulti(PostFields.PostId == (Guid)key) > 0;
            }
            return false;
        }

        protected override bool OnAddData(PostData data, ITransaction transaction)
        {
            if (!ValidatePost(data, transaction))
            {
                return false;
            }
            string parentPath = data.ParentId.HasValue ? GetPost(data.ParentId.Value).Path : string.Empty;
            var childNodes = data.ParentId.HasValue ? GetChildNodes(data.ParentId.Value) : GetRootNodes();
            string path = parentPath + childNodes.Count().ToString("X").PadLeft(4, '0');
            var entity = new PostEntity
            {

                ParentPostId = data.ParentId,
                PostName = data.PostName,
                PostLevel = data.PostLevel,
                PostId = data.PostId,
                Comments = data.Comments,
                NodeLevel = data.NodeLevel

            };
            transaction.Add(entity);
            if (entity.Save())
            {
                data.PostId = entity.PostId;
                data.Path = path;
                return true;
            }
            return false;
        }

        protected override bool OnModifyData(object key, PostData data, ITransaction transaction)
        {
            if (!ValidatePost(data, transaction))
            {
                return false;
            }
            var entity = new PostEntity();
            transaction.Add(entity);
            entity.FetchUsingPK((Guid)key);
            if (entity.IsNew)
            {
                return false;
            }
            var path = GetPost((Guid)key).Path;
            entity.ParentPostId = data.ParentId;
            entity.PostId = data.PostId;
            entity.PostName = data.PostName;
            entity.PostLevel = data.PostLevel;
            entity.NodeLevel = data.NodeLevel;
            entity.Comments = data.Comments;

            return entity.Save();
        }

        #endregion

        #region Overrides of HierarchyCachableService<PostData>

        protected override object GetParentKey(PostData data)
        {
            return data.ParentId;
        }

        protected override IEnumerable<PostData> OnLoadChildNodes(object parentKey,
                                                                               ITransaction transaction)
        {
            var meta = new LinqMetaData(transaction);
            var list = (from post in meta.Post
                        where post.ParentPostId == (Guid?)parentKey
                        select post).ToList();
            return list.Select(post => GetPostData(post));
        }

        #endregion

        #region Overrides of PrimitiveHierarchyService<PostData>

        protected override IEnumerable<PostData> OnLoadRootNodes(ITransaction transaction)
        {
            var meta = new LinqMetaData(transaction);
            var list = (from post in meta.Post
                        where post.ParentPostId == null
                        select post).ToList();
            return list.Select(post => GetPostData(post));
        }

        #endregion

        private static PostData GetPostData(PostEntity entity)
        {
            return new PostData
            {
                ParentId = entity.ParentPostId,
                PostId = entity.PostId,
                PostName = entity.PostName,
                PostLevel = entity.PostLevel,
                Comments = entity.Comments,
                NodeLevel = entity.NodeLevel,


            };
        }
        private bool ValidatePost(PostData data, ITransaction transaction)
        {
            var meta = new LinqMetaData(transaction);
            var list = (from post in meta.Post
                        where post.PostName == data.PostName && post.PostId != data.PostId
                        select post).ToList();

            if (list.Count > 0)
            {
                data.SetError("PostName",
                             string.Format("The Position '{0}' has existed.", data.PostName));
                return false;
            }

            return true;
        }


    }
}
